home *** CD-ROM | disk | FTP | other *** search
/ Mac Easy 2010 May / Mac Life Ubuntu.iso / casper / filesystem.squashfs / usr / share / pyshared / AppInstall / widgets / AppDescView.py next >
Encoding:
Python Source  |  2009-03-31  |  11.1 KB  |  252 lines

  1. import gtk
  2. from ReleaseNotesViewer import ReleaseNotesViewer
  3. from gettext import gettext as _
  4. import re
  5. import pango
  6. import gobject
  7.  
  8. class AppDescView(ReleaseNotesViewer):
  9.     def __init__(self):
  10.         ReleaseNotesViewer.__init__(self)
  11.         self.set_wrap_mode(gtk.WRAP_WORD)
  12.         self.set_pixels_below_lines(3)
  13.         self.set_right_margin(6)
  14.         self.set_left_margin(6)
  15.         atk_desc = self.get_accessible()
  16.         atk_desc.set_name(_("Description"))
  17.  
  18.     def hook(self, cache, menu, icons, tooltips, distro):
  19.         self.cache = cache
  20.         self.menu = menu
  21.         self.icons = icons
  22.         self.tooltips = tooltips
  23.         self.distro = distro
  24.  
  25.     def show_description(self, item):
  26.         """Collect and show some information about the package that 
  27.            contains the selected application"""
  28.         details = []
  29.         clean_desc = ""
  30.         short_desc = ""
  31.         version = ""
  32.         desktop_environment = ""
  33.         icons = []
  34.         homepage = ""
  35.         style = self.get_style()
  36.  
  37.         if self.menu.itemAvailable(item):
  38.             pkg = self.cache[item.pkgname]
  39.             homepage = pkg.homepage
  40.             rough_desc = pkg.description.rstrip(" \n\t")
  41.             # the first line is the short description
  42.             first_break = rough_desc.find("\n")
  43.             short_desc = rough_desc[:first_break].rstrip("\n\t ")
  44.             rough_desc = rough_desc[first_break + 1:].lstrip("\n\t ")
  45.                     
  46.             # so some regular expression magic on the description
  47.             #print "original: "
  48.             #print rough_desc
  49.             # replace all multiple spaces with a single space
  50.             #print "\n\neliminate multiple spaces"
  51.             p = re.compile(r'\ \ +', re.MULTILINE)
  52.             rough_desc = p.sub(" ", rough_desc)
  53.             #print rough_desc
  54.  
  55.             #print "\n\nAdd a newline before each bullet:\n"
  56.             p = re.compile(r'^(\s|\t)*(\*|0|-)', re.MULTILINE)
  57.             rough_desc = p.sub('\n*', rough_desc)
  58.             #print rough_desc
  59.  
  60.             #print "\n\nreplace all newlines by spaces\n"
  61.             p = re.compile(r'\n', re.MULTILINE)
  62.             rough_desc = p.sub(" ", rough_desc)
  63.             #print rough_desc
  64.  
  65.             #print "\n\nreplace all multiple spaces by newlines:\n"
  66.             p = re.compile(r'\s\s+', re.MULTILINE)
  67.             rough_desc = p.sub("\n", rough_desc)
  68.  
  69.             lines = rough_desc.split('\n')
  70.             #print "\n\nrough: \n"
  71.             #print rough_desc
  72.  
  73.             for i in range(len(lines)):
  74.                 if lines[i].split() == []:
  75.                     continue
  76.                 first_chunk = lines[i].split()[0]
  77.                 if first_chunk == "*":
  78.                     p = re.compile(r'\*\s*', re.MULTILINE)
  79.                     lines[i] = p.sub("", lines[i])
  80.                     #FIXME: USE THE UTF BULLET
  81.                     clean_desc += "* %s\n" % lines[i]
  82.                 else:
  83.                     clean_desc += "%s\n" % lines[i]
  84.             #print clean_desc
  85.             if not clean_desc:
  86.                 clean_desc = item.comment
  87.         else:
  88.             msg = _("%s cannot be installed" % item.name)
  89.             # check if we have seen the component
  90.             for it in self.cache._cache.FileList:
  91.                 # FIXME: we need to exclude cdroms here. the problem is
  92.                 # how to detect if a PkgFileIterator is pointing to a cdrom
  93.                 if (it.Component != "" and it.Component == item.component) or\
  94.                    (item.architectures and \
  95.                     not self.cache.getArch() in item.architectures):
  96.                     # warn that this app is not available on this plattform
  97.                     details.append(_("%s cannot be installed on your "
  98.                                      "computer type (%s). Either the "
  99.                                      "application requires special "
  100.                                      "hardware features or the vendor "
  101.                                      "decided to not support your "
  102.                                      "computer type.") % (item.name, 
  103.                                      self.cache.getArch()))
  104.                     break
  105.             # check if it comes from a third party repository and
  106.             # display message then
  107.             if item.channel:
  108.                 details.append(_("%s is available in the third party software " 
  109.                                  "channel '%s'. To install it, please "
  110.                                  "click on the checkbox to activate the "
  111.                                  "software channel.") % 
  112.                                (item.name, item.channel))
  113.  
  114.         # mutliple apps per pkg check
  115.         s = ""
  116.         if self.menu.pkg_to_app.has_key(item.name) and \
  117.            len(self.menu.pkg_to_app[item.name]) > 1:
  118.             s = _("This application is bundled with "
  119.                   "the following applications: ")
  120.             apps = self.menu.pkg_to_app[item.name]
  121.             s += ", ".join([pkg.name for pkg in apps])
  122.             details.append(s)
  123.  
  124.         # init the textview that shows the description of the app
  125.         buffer = self.get_buffer()
  126.         buffer.set_text("")
  127.         # remove all old tags
  128.         tag_table = buffer.get_tag_table()
  129.         tag_table.foreach((lambda tag, table: table.remove(tag)), tag_table)
  130.         iter = buffer.get_start_iter()
  131.         # we need the default font size for the vertically justification
  132.         pango_context = self.get_pango_context()
  133.         font_desc = pango_context.get_font_description()
  134.         font_size = font_desc.get_size() / pango.SCALE
  135.         if item.iconname != "":
  136.             # justify the icon and the app name
  137.             if font_size * pango.SCALE_LARGE > 32:
  138.                 icon_size = 32
  139.                 adjust_vertically = 0
  140.             elif font_size * pango.SCALE_LARGE < 10:
  141.                 icon_size = 24
  142.                 adjust_vertically = (icon_size - font_size * pango.SCALE_LARGE)\
  143.                                     /2
  144.             else:
  145.                 icon_size = 32
  146.                 adjust_vertically = (icon_size - font_size * pango.SCALE_LARGE)\
  147.                                     / 2
  148.             tag_name = buffer.create_tag("app-icon",
  149.                                          right_margin=6,
  150.                                          pixels_above_lines=6)
  151.             tag_name = buffer.create_tag("app-name",
  152.                                          rise=adjust_vertically * pango.SCALE,
  153.                                          pixels_above_lines=6,
  154.                                          weight=pango.WEIGHT_BOLD,
  155.                                          scale=pango.SCALE_LARGE)
  156.             try:
  157.                 icon_pixbuf = self.icons.load_icon(item.iconname, icon_size, 0)
  158.             except gobject.GError:
  159.                 try:
  160.                     icon_pixbuf = self.icons.load_icon("applications-other", 
  161.                                                        icon_size, 0)
  162.                 except gobject.GError:
  163.                     icon_pixbuf = self.icons.load_icon(gtk.STOCK_MISSING_IMAGE,
  164.                                                        icon_size, 0)
  165.             buffer.insert_pixbuf(iter, icon_pixbuf)
  166.             (start_iter, end_iter,) = buffer.get_bounds()
  167.             buffer.apply_tag_by_name("app-icon", start_iter, end_iter)
  168.             buffer.insert_with_tags_by_name(iter, " %s" % item.name, "app-name")
  169.         else:
  170.             tag_name = buffer.create_tag("app-name",
  171.                                          weight=pango.WEIGHT_BOLD,
  172.                                          pixels_above_lines=6,
  173.                                          scale=pango.SCALE_LARGE)
  174.             buffer.insert_with_tags_by_name(iter, "%s" % item.name, "app-name")
  175.  
  176.         emblems = self.distro.get_app_emblems(item, self.cache)
  177.         if short_desc != "": 
  178.             tag_name = buffer.create_tag("short-desc",
  179.                                          weight=pango.WEIGHT_BOLD)
  180.             buffer.insert_with_tags_by_name(iter,
  181.                                             "\n%s" % short_desc,
  182.                                             "short-desc")
  183.             for emblem in emblems:
  184.                 # not all emblems have got an icon
  185.                 if not emblem[0]:
  186.                     continue
  187.                 image_emblem = gtk.Image()
  188.                 image_emblem.set_from_icon_name(emblem[0],
  189.                                                 gtk.ICON_SIZE_MENU)
  190.                 image_emblem.set_pixel_size(16)
  191.                 event = gtk.EventBox()
  192.                 # use the base color of the textview for the image
  193.                 # FIXME: send the selected signal from the anchor 
  194.                 #        to the widget
  195.                 for state in [gtk.STATE_NORMAL, gtk.STATE_ACTIVE,
  196.                               gtk.STATE_PRELIGHT, gtk.STATE_SELECTED,
  197.                               gtk.STATE_INSENSITIVE]:
  198.                     event.modify_bg(state,
  199.                                     style.base[state])
  200.                 event.add(image_emblem)
  201.                 if emblem[1] != None:
  202.                     self.tooltips.set_tip(event, emblem[1])
  203.                 buffer.insert(iter, " ")
  204.                 anchor = buffer.create_child_anchor(iter)
  205.                 self.add_child_at_anchor(event,
  206.                                          anchor)
  207.                 event.show()
  208.                 image_emblem.show()
  209.         if clean_desc != "": 
  210.             buffer.insert(iter, "\n%s" % clean_desc)
  211.         if homepage:
  212.             buffer.insert(iter, _("\nHomepage: %s\n") % homepage)
  213.         if version != "":
  214.             buffer.insert(iter, _("Version: %s (%s)") % (version, item.pkgname))
  215.         if len(details) > 0:
  216.             for x in details:
  217.                 buffer.insert(iter, "\n%s" % x)
  218.         # add maintenance status
  219.         #buffer.insert(iter, " ")
  220.         #anchor = buffer.create_child_anchor(iter)
  221.         #foo = gtk.Frame(self.distro.get_maintenance_status(item, self.cache))
  222.         #foo.show()
  223.         #self.add_child_at_anchor(foo, anchor)
  224.         buffer.create_tag("maint-status", 
  225.                           scale_set=True,
  226.                           scale=pango.SCALE_SMALL,
  227.                           foreground="#888")
  228.         #                  foreground_gdk=style.base[gtk.STATE_INSENSITIVE])
  229.         m = self.distro.get_maintenance_status(item, self.cache)
  230.         buffer.insert_with_tags_by_name(iter, "\n%s" % m, "maint-status")
  231.  
  232.     def show_message(self, header, msg):
  233.         """ Show a quick introduction to gnome-app-install 
  234.             in the description view"""
  235.         buffer = self.get_buffer()
  236.         buffer.set_text("")
  237.         iter = buffer.get_start_iter()
  238.         tag_header = buffer.get_tag_table().lookup("header")
  239.         if not tag_header:
  240.             tag_header = buffer.create_tag("header",
  241.                                            scale = pango.SCALE_LARGE,
  242.                                            weight = pango.WEIGHT_BOLD,
  243.                                            pixels_above_lines=6)
  244.         if header:
  245.             buffer.insert_with_tags(iter, "%s\n" % header, 
  246.                                     tag_header)
  247.         buffer.insert(iter, msg)
  248.  
  249.     def clear_description(self):
  250.         buffer = self.get_buffer()
  251.         buffer.set_text("")
  252.